#include "ecatmasteracontis.h"
#include "ecatDemoCommon.h"
#include "DCDemo.h"

#include "messagelog.h"

extern  int  testMain(int nArgc, char* ppArgv[]);


EcatMasterAcontis::EcatMasterAcontis(int pthread_priority_in, int pthread_schedule_in)
    :EcatMasterBase(pthread_priority_in,pthread_schedule_in)
{
}


int EcatMasterAcontis::stop()
{
    system("rmmod atemsys-rt.ko");
    isShutDown=true;
    bRun = false;
    if(masterCurrentState>eMasterPreOP)
        setMasterState(eMasterPreOP);

    return 1;
}

void* EcatMasterAcontis::run(void *)
{

//    system("/etc/init.d/ethercat stop");
    system("rmmod e1000e");
    system("insmod atemsys-rt.ko");

  //  QString args_str=QString(argv[0])+"-i8254x 1 1 -v 3  -perf -f tc-2017.5.9-xyf-project.xml -auxclk 1000"
    QString args_str = "myapp " +robCtl.busManager->cmdLine+ " -f "+robCtl.busManager->eniFile;
    QStringList argvList = args_str.split(" ", QString::SkipEmptyParts );

    int argc=argvList.size();
    char* my_argv[argc] ;
    for(int i=0;i<argvList.size();i++){
        QByteArray ba = argvList.at(i).toLatin1();
        my_argv[i]=new char[20];
        memset( my_argv[i], 0, 20 );
        memcpy( my_argv[i], (char*)ba.data(),  ba.length() );

         qDebug()<<i<<my_argv[i];
       // printf("%d, %s", i, my_argv[i] );
    }

    qDebug()<<" ============ ethercat master start =============";

    isrunning = true;

    int  dwRes = testMain( argc, my_argv );
    if (EC_E_NOERROR != dwRes)
    {
        qDebug()<<"\n\n\n========== errr =============\n\n\n";
    }else{
        qDebug()<<"\n\n\n=========== ok =============\n\n\n";
    }

    isRun=false;
    canquit=true;
    printf("Ethercat master had stopped!\n");
    return NULL;
}

int EcatMasterAcontis::setAlias( int node , unsigned short alias )
{

}

int EcatMasterAcontis::sdoUpload(int node
                                 , int rObIndex
                                 , int rObSubIndex
                                 , LONG64 &rData
                                 , int &rDataLen)
{

    ///
    /// \brief pbyData

    unsigned char pbyData[8]={0};
    int dwRes=0;
    EC_T_DWORD result_size=0;

    dwRes = ecatCoeSdoUpload(node,
                             rObIndex, rObSubIndex,
                             pbyData, rDataLen, &result_size,
                             5000, 0);
    if (dwRes != EC_E_NOERROR)
    {
        printf("sdo: error in COE SDO Download! %x (0x%x)\n"
               , rObIndex, dwRes);
        return 0;
    }

    switch(result_size){
    case 1:  rData = pbyData[0] ;
        break;
    case 2:  rData = bytes_to_uint16( pbyData );
        break;
    case 4: rData =  bytes_to_uint32(  pbyData );
        break;
    case 8:  rData = bytes_to_uint64(  pbyData );
        break;
    default: printf("不支持的sdo数据长度:wDataLen=%d \n",rDataLen);
        return 0;
    }

    return 1;
}

int EcatMasterAcontis::sdoDownload(int node
                                   , int wObIndex
                                   , int wObSubIndex
                                   , LONG64 wData
                                   , int wDataLen )
{
  /*  EC_T_BYTE  pbyData[8];
    int dwRes=0;
    switch(wDataLen){
    case 1:  *pbyData = wData;
        break;
    case 2:  *pbyData = EC_HTONS(wData);
        break;
    case 4:  *pbyData = EC_HTONL(wData);
        break;
    case 8:  *pbyData = EC_HTONLL(wData);
        break;
    default: printf("不支持的sdo数据长度:wDataLen=%d \n",wDataLen);
        return 0;
    }*/
    unsigned char pbyData[8];
    int dwRes=0;
    switch(wDataLen){
    case 1:  pbyData[0] = wData;
        break;
    case 2:  uint16_to_bytes( wData, pbyData );
        break;
    case 4:  uint32_to_bytes( wData, pbyData );
        break;
    case 8:  uint64_to_bytes( wData, pbyData );
        break;
    default: printf("不支持的sdo数据长度:wDataLen=%d \n",wDataLen);
        return 0;
    }

    dwRes = ecatCoeSdoDownload(node,
                               wObIndex, wObSubIndex,
                               pbyData, wDataLen,
                               5000, 0);
    if (dwRes != EC_E_NOERROR)
    {
        printf("sdo: error in COE SDO Download! %x (0x%x)\n"
               , wObIndex, dwRes);
        return 0;
    }
    return 1;
}

void EcatMasterAcontis::addMsg(int messageLevel,
             std::string componentName,
             std::string messageType,
             int messageCode,
             int robotId,
             int parameter1 ,
             int parameter2 ,
             int parameter3 ,
             int parameter4 )
{
    struct timeval tv_begin ;
    gettimeofday(&tv_begin, NULL);

    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
    tmpMsg.time = tv_begin.tv_sec;

    QString infomationStr;
    switch(messageCode)
    {
    case 301:
    {
        infomationStr = QObject::tr( "机器人轴别名(%1)busDev.xml中node(%2)与实际物理node不一致，请检查物理接线或配置")
                .arg(parameter1).arg(parameter2);
    }
        break;
    case 300:
    {
        infomationStr = QObject::tr( "机器人轴别名%1在总线配置中没有找到!").arg(parameter1) ;
    }
        break;
    case 400:
        break;
        /**********************/
        /* error notification */
        /**********************/
    case 401:    /* ERR|1 */
        infomationStr = QObject::tr( "cyclic command: working counter error!") ;
        break;
    case 402:    /* ERR|2 */
        infomationStr = QObject::tr( "master init command: working counter error !") ;
        break;
    case 403:     /* ERR|3 */
        infomationStr = QObject::tr( "slave init command: working counter error!") ;
        break;
    case 407:    /* ERR|7 */
        infomationStr = QObject::tr( "EoE mbox send: working counter error !") ;
        break;
    case 408:    /* ERR|8 */
        infomationStr = QObject::tr( " CoE mbox send: working counter error !");
        break;//\{ (\n|\s|.)*\ }
    case 409:    /* ERR|9 */
        infomationStr = QObject::tr( "FoE mbox send: working counter error !");
        break;
    case 434:    /* ERR|34 */
        infomationStr = QObject::tr( "VoE mbox send: working counter error !") ;
        break;
    case 410: /* ERR|10 */
        if(eMasterOP!=getMasterState())
            return;
        infomationStr = QObject::tr( "Got no response on a sent Ethernet frame !");
        break;
    case 411: /* ERR|11 */
        infomationStr = QObject::tr( "Got no or unexpected response on a sent ecat init command from slave  !"); break;
    case 412:   /* ERR|12 */
        infomationStr = QObject::tr( "Got no response on a sent ecat master init command !"); break;
    case 414:     /* ERR|14 */
        infomationStr = QObject::tr( "Timeout when waiting for mailbox init command response  !"); break;
    case 415:     /* ERR|15 */
        infomationStr = QObject::tr( "Not all slave devices are in operational state when receiving cyclic frames !"); break;
    case 416: /* ERR|16 */
        infomationStr = QObject::tr( " Ethernet link (cable) not connected  !"); break;
    case 418:         /* ERR|18 */
        infomationStr = QObject::tr( "Redundancy: line break detected !"); break;
    case 419:  /* ERR|19 */
        infomationStr = QObject::tr( "At least one slave is in error state when receiving cyclic frames (BRD AL-STATUS) !");
        break;
    case 420:     /* ERR|20 */
        infomationStr = QObject::tr( "Slave error (AL status code) !");
         break;
    case 421:       /* ERR|21 */
        infomationStr = QObject::tr( "Station address lost (or slave missing) - FPRD to AL_STATUS failed  !");
         break;
#ifdef INCLUDE_SOE_SUPPORT
    case 423:    /* ERR|23 */
        infomationStr = QObject::tr( "SoE mbox send: working counter error !");
         break;
    case 424:         /* ERR|24 */
        infomationStr = QObject::tr( "SoE mbox write responded with an error !");
         break;
#endif
    case 425:   /* ERR|25 */
        infomationStr = QObject::tr( "CoE mbox SDO abort !");
         break;
    case 426:  /* ERR|26 */
        infomationStr = QObject::tr( "Client registration dropped, possibly call to ecatConfigureMaster by other thread (RAS) !");
         break;
    case 427:  /* ERR|27 */
        infomationStr = QObject::tr( "Redundancy: line is repaired !");
        break;
#ifdef INCLUDE_FOE_SUPPORT
    case 428:   /* ERR|28 */
        infomationStr = QObject::tr( "FoE mbox abort  !");
         break;
#endif
    case 429: /* ERR|29 */
        infomationStr = QObject::tr( "invalid mail box data received  !");
         break;
    case 430:         /* ERR|30 */
        infomationStr = QObject::tr( " PDI Watchdog expired on slave, thrown by IST !");
         break;
    case 431:      /* ERR|31 */
        infomationStr = QObject::tr( "slave not supported (if redundancy is activated and slave doesn't fully support autoclose  !");
         break;
    case 432:      /* ERR|32 */
        infomationStr = QObject::tr( "slave in unexpected state !");
         break;
    case 433:     /* ERR|33 */
        infomationStr = QObject::tr( " All slave devices are in operational state !");
         break;
    case 435:       /* ERR|35 */
        infomationStr = QObject::tr( "EEPROM checksum error detected !");
         break;
    case 436:                /* ERR|36 */
        infomationStr = QObject::tr( " Crossed lines detected  !");
         break;
    case 437:         /* ERR|37 */
        infomationStr = QObject::tr( "Junction redundancy change  !");
         break;
    case 438:      /* ERR|38 */
        infomationStr = QObject::tr( "slaves in unexpected state !");
         break;
    case 439:         /* ERR|39 */
        infomationStr = QObject::tr( " Slaves error (AL status code) !");
         break;
    case 440:       /* ERR|40 */
        infomationStr = QObject::tr( "Frameloss after Slave !");
         break;
    }

    tmpMsg.MessageInformation = infomationStr.toStdString();
    MessageLog::getInstance()->addMessage(tmpMsg);

}
